package com.neouton.crm.paymentPlan.service.impl;


import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mysql.cj.util.StringUtils;
import com.neouton.common.util.AuthUtils;
import com.neouton.common.util.PageUtil;
import com.neouton.common.util.ReportUtils;
import com.neouton.crm.dictionary.entity.DictionaryLookupItemVO;
import com.neouton.crm.dictionary.service.IDictionaryService;
import com.neouton.crm.entity.SysUserEntity;
import com.neouton.crm.payRecords.entity.PaymentRecords;
import com.neouton.crm.payRecords.entity.PaymentRequest;
import com.neouton.crm.payRecords.entity.PaymentTable;
import com.neouton.crm.payRecords.mapper.PaymentRecordsMapper;
import com.neouton.crm.paymentPlan.entity.PaymentPlan;
import com.neouton.crm.paymentPlan.mapper.PaymentPlanMapper;
import com.neouton.crm.paymentPlan.service.PaymentPlanService;
import com.neouton.crm.receiptRecords.entity.ReceiptRecords;
import com.neouton.crm.receiptRecords.entity.ReceiptTable;
import com.neouton.crm.receiptRecords.mapper.ReceiptRecordsMapper;
import com.neouton.feginClient.FeginService;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

/**
* @author Mose
* @description 针对表【payment_plan(付款计划)】的数据库操作Service实现
* @createDate 2023-01-12 16:25:52
*/
@Service
public class PaymentPlanServiceImpl implements PaymentPlanService {

    @Resource
    private PaymentPlanMapper paymentPlanMapper;

    @Resource
    private IDictionaryService dictionaryService;

    @Resource
    FeginService feginService;

    @Resource
    private ReceiptRecordsMapper receiptRecordsMapper;

    @Resource
    private PaymentRecordsMapper paymentRecordsMapper;

    @Override
    public List<PaymentPlan> getPayPlanList(PaymentPlan entity) {
        return paymentPlanMapper.getPayPlanList(entity);
    }

    @Override
    public void savePayPlan(List<PaymentPlan> paymentPlans) {
        paymentPlanMapper.savePayPlan(paymentPlans);
    }

    @Override
    public void updatePayPlanById(PaymentPlan entity) {
        paymentPlanMapper.updatePayPlanById(entity);
    }

    @Override
    public PaymentPlan queryPaymentPlanByPurchaseOrderID(PaymentPlan paymentPlan) {
        return paymentPlanMapper.queryPaymentPlanByPurchaseOrderID(paymentPlan);
    }

    @Override
    public List<PaymentPlan> getPaymentPlanByPurchaseOrderID(PaymentPlan paymentPlan) {
        return paymentPlanMapper.getPaymentPlanByPurchaseOrderID(paymentPlan);
    }
    @Override
    public List<PaymentPlan> queryPayPlanByPidAndPlanPeriod(PaymentPlan paymentPlan) {
        List<String> planPeriods = new ArrayList<>();
        if(!StringUtils.isNullOrEmpty(paymentPlan.getPlanPeriod())){
            if(paymentPlan.getPlanPeriod().indexOf(",") >0) {
                for (String planPeriod:paymentPlan.getPlanPeriod().split(",")) {
                    planPeriods.add(planPeriod);
                }
                paymentPlan.setPlanPeriods(planPeriods);
                paymentPlan.setPlanPeriod(null);
            }
        }
        return paymentPlanMapper.queryPayPlanByPidAndPlanPeriod(paymentPlan);
    }

    @Override
    public void updatePayPlansByIdAndPlanPeriod(List<PaymentPlan> paymentPlans) {
        if(paymentPlans.size()>0){
            paymentPlanMapper.updatePayPlansByIdAndPlanPeriod(paymentPlans);
        }
    }


    @Override
    public List<PaymentPlan> queryPayPlanBackByPidAndPlanPeriod(PaymentPlan paymentPlan) {
        List<String> planPeriods = new ArrayList<>();
        if(!StringUtils.isNullOrEmpty(paymentPlan.getPlanPeriod())){
            if(paymentPlan.getPlanPeriod().indexOf(",") >0) {
                for (String planPeriod:paymentPlan.getPlanPeriod().split(",")) {
                    planPeriods.add(planPeriod);
                }
                paymentPlan.setPlanPeriods(planPeriods);
                paymentPlan.setPlanPeriod(null);
            }
        }
        return paymentPlanMapper.queryPayPlanBackByPidAndPlanPeriod(paymentPlan);
    }
    /**
     * 分页查询
     *
     * @param page
     * @param entity
     * @return
     */
    public PageUtil<PaymentPlan> queryPaymentPlansByPage(IPage page, PaymentPlan entity, String token){
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"paymentPlans", token);
        IPage<PaymentPlan> iPage = paymentPlanMapper.queryPaymentPlansByPage(page, entity, userList);
        List<PaymentPlan> list = iPage.getRecords();
        if(!list.isEmpty()){
            BigDecimal paymentMoneyPage = new BigDecimal(0);
            BigDecimal payedMoneyPage = new BigDecimal(0);
            BigDecimal receiveMoneyPage = new BigDecimal(0);
            for (PaymentPlan paymentPlan: list) {
                ReceiptTable receiptTable = new ReceiptTable();
                if(paymentPlan.getPurchaseOrder() !=null){
                    receiptTable.setPurchaseOrderId(paymentPlan.getPurchaseOrder().getPurchaseId());
                    receiptTable.setPlanPeriod(paymentPlan.getPlanPeriod());
                    PaymentTable paymentTable = new PaymentTable();
                    paymentTable.setPurchaseOrderId(paymentPlan.getPurchaseOrder().getPurchaseId());
                    paymentTable.setPlanPeriod(paymentPlan.getPlanPeriod());
                    List<ReceiptTable> receiptTableList = receiptRecordsMapper.queryReceiptTablesByIdAndPlanPeriod(receiptTable);
                    List<PaymentTable> paymentTables = paymentRecordsMapper.queryPayTablesByIdAndPlanPeriod(paymentTable);
                    BigDecimal recenum = new BigDecimal("0");
                    for (ReceiptTable rece: receiptTableList) {
                        recenum =  recenum.add(new BigDecimal(rece.getReceiptMoney()));
                    }
                    BigDecimal paynum = new BigDecimal("0");
                    for (PaymentTable ptable: paymentTables) {
                        //通过付款申请ID查看是否存在付款记录
                        List<PaymentRecords> paymentRecords = paymentRecordsMapper.queryPaymentRecordsByPayRequestId(ptable.getPayRequestId());
                        if(paymentRecords != null && paymentRecords.size()>0){
                            paynum =  paynum.add(new BigDecimal(ptable.getPayMoney()));
                        }
                    }
                    paymentPlan.setReceiveMoney(recenum.toString());
                    paymentPlan.setPayedMoney(paynum.toString());
                }
                if(!StringUtils.isNullOrEmpty(paymentPlan.getPaymentMoney())){
                    paymentMoneyPage = paymentMoneyPage.add(new BigDecimal(paymentPlan.getPaymentMoney()));
                }
                if(!StringUtils.isNullOrEmpty(paymentPlan.getPayedMoney())){
                    payedMoneyPage = payedMoneyPage.add(new BigDecimal(paymentPlan.getPayedMoney()));
                }
                if(!StringUtils.isNullOrEmpty(paymentPlan.getReceiveMoney())){
                    receiveMoneyPage = receiveMoneyPage.add(new BigDecimal(paymentPlan.getReceiveMoney()));
                }

            }
            list.get(0).setPaymentMoneyPage(String.valueOf(paymentMoneyPage));
            list.get(0).setPayedMoneyPage(String.valueOf(payedMoneyPage));
            list.get(0).setReceiveMoneyPage(String.valueOf(receiveMoneyPage));
            iPage.setRecords(list);
        }
        return new PageUtil(iPage);
    }

    /**
     * 回款计划列表导出
     *
     * @param response
     */
    public void exportPaymentPlans(HttpServletResponse response, PaymentPlan entit, String token) throws Exception{
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"paymentPlans", token);
        List<PaymentPlan> paymentPlans = paymentPlanMapper.queryAllPaymentPlans(entit, userList);
        List<String> codes = new ArrayList<>();
        codes.add("payPlanPeriodNum");
        codes.add("payMethod");
        codes.add("payCompany");
        codes.add("payAttr");
        codes.add("payIsNot");
        codes.add("receiveInvoice");
        Map<String, List<DictionaryLookupItemVO>> stringListMap = dictionaryService.queryDictionaryLookupInfo(null, codes);

        for (int i = 0; i < paymentPlans.size(); i++) {
            PaymentPlan paymentPlan = paymentPlans.get(i);
            //付款期次
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("payPlanPeriodNum") ){
                if(dictionaryLookupItemVO.getItemCode().equals(paymentPlan.getPlanPeriod()+"")){
                    paymentPlan.setPlanPeriodStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("payMethod") ){
                if(dictionaryLookupItemVO.getItemCode().equals(paymentPlan.getPayMethod()+"")){
                    paymentPlan.setPayMethodStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("payCompany") ){
                if(dictionaryLookupItemVO.getItemCode().equals(paymentPlan.getPayCompany()+"")){
                    paymentPlan.setPayCompanyStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("payAttr") ){
                if(dictionaryLookupItemVO.getItemCode().equals(paymentPlan.getPayAttr()+"")){
                    paymentPlan.setPayAttrStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("payIsNot") ){
                if(dictionaryLookupItemVO.getItemCode().equals(paymentPlan.getPayIsNot()+"")){
                    paymentPlan.setPayIsNotStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("receiveInvoice") ){
                if(dictionaryLookupItemVO.getItemCode().equals(paymentPlan.getReceiveInvoice()+"")){
                    paymentPlan.setReceiveInvoiceName(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            if(paymentPlan.getPurchaseCategories() != null && paymentPlan.getPurchaseOrder() != null){
                if(0 == paymentPlan.getPurchaseCategories()){
                    paymentPlan.setPurchaseCategoriesStr("机会采购");
                    paymentPlan.setProjectManageTheme(paymentPlan.getPurchaseOrder().getOpportunityTheme());
                }else{
                    paymentPlan.setPurchaseCategoriesStr("项目采购");
                    paymentPlan.setProjectManageTheme(paymentPlan.getPurchaseOrder().getProjectManageTheme());
                }
            }

            if(paymentPlan.getPurchaseOrder() != null){
                if(0 == paymentPlan.getPurchaseOrder().getApproval().getApprovalStatus()){
                    paymentPlan.getPurchaseOrder().setApprovalStr("审批中");
                }else if(1 == paymentPlan.getPurchaseOrder().getApproval().getApprovalStatus()){
                    paymentPlan.getPurchaseOrder().setApprovalStr("已通过");
                }else if(2 == paymentPlan.getPurchaseOrder().getApproval().getApprovalStatus()){
                    paymentPlan.getPurchaseOrder().setApprovalStr("已驳回");
                }else if(3 == paymentPlan.getPurchaseOrder().getApproval().getApprovalStatus()){
                    paymentPlan.getPurchaseOrder().setApprovalStr("已撤回");
                }else if(5 == paymentPlan.getPurchaseOrder().getApproval().getApprovalStatus()){
                    paymentPlan.getPurchaseOrder().setApprovalStr("撤回中");
                }
            }

            paymentPlan.setMoneyDateStr(String.format("%tY-%<tm-%<td",paymentPlan.getMoneyDate()));
        }

        //获取yml模板位置
        YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
        String path = "application.yml";
        factoryBean.setResources(new ClassPathResource(path));
        Properties properties = factoryBean.getObject();
        String paymentPlansTemplatePath = String.valueOf(properties.get("report.paymentPlansTemplate"));

        //依据根目录获取模板位置
        TemplateExportParams params = new TemplateExportParams(paymentPlansTemplatePath);
        Map<String, Object> map = new HashMap<>();
        map.put("paymentPlansInfos",paymentPlans);
        ReportUtils.exportExcel(params,map,"回款计划列表",response);

    }

    public List<SysUserEntity> queryUserList(Integer userId,String authCode, String token) {
        List<SysUserEntity> userList = new ArrayList<>();
        List<SysUserEntity> authUserIList = dictionaryService.queryAuthUserIdsByCode(authCode);
        boolean result = false;
        for (SysUserEntity user:authUserIList) {
            if (Objects.equals(user.getUserId(), userId)) {
                result = true;
            }
        }
        if (result) {
            userList = feginService.getUserIgnoreFlag(token).getResult();
        } else {
            SysUserEntity user = feginService.searchUserInfoByIds(userId,token).getResult();
            if (user.getIsLeader() == 1) {
                userList = feginService.recursiveQueryAllUserByLeaderId(userId, token).getResult();
            }
            userList.add(user);
        }
        return userList;
    }
}
